package espacokidsadm.web.validator;

import java.util.InputMismatchException;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.FacesValidator;
import javax.faces.validator.Validator;
import javax.faces.validator.ValidatorException;

@FacesValidator("CpfCnpjValidator")
public class CpfCnpjValidator implements Validator{

	@Override
	public void validate(FacesContext context, UIComponent componente, Object value) throws ValidatorException {
		if(String.valueOf(value).length() <= 11){
			if(!validaCPF(String.valueOf(value))){
				FacesMessage message = new FacesMessage();
				message.setSeverity(FacesMessage.SEVERITY_ERROR);
				message.setSummary("'" + value.toString() + "' NÃO é um CPF válido !");
				throw new ValidatorException(message);
			}
		}else if(!isCNPJ(String.valueOf(value))){
			FacesMessage message = new FacesMessage();
			message.setSeverity(FacesMessage.SEVERITY_ERROR);
			message.setSummary("'" + value.toString() + "' NÃO é um CNPJ válido !");
			throw new ValidatorException(message);
		}
		
	}

	 /**
	* Valida CPF do usuário. Não aceita CPF's padrões como
     * 11111111111 ou 22222222222
     *
     * @param cpf String valor com 11 dígitos
     */
     private static boolean validaCPF(String cpf) {
          if (cpf == null || cpf.length() != 11 || 	isCPFPadrao(cpf))
               return false;
          try {
               Long.parseLong(cpf);
          } catch (NumberFormatException e) { // CPF não possui somente números
        	  return false;
          }
 
          return calcDigVerif(cpf.substring(0, 9)).equals(cpf.substring(9, 11));
     }
 
     /**
     *
     * @param cpf String valor a ser testado
     * @return boolean indicando se o usuário entrou com um CPF padrão
     */
     private static boolean isCPFPadrao(String cpf) {
          if (cpf.equals("11111111111") || cpf.equals("22222222222")
        || cpf.equals("33333333333")
        || cpf.equals("44444444444")
        || cpf.equals("55555555555")
        || cpf.equals("66666666666")
        || cpf.equals("77777777777")
        || cpf.equals("88888888888")
        || cpf.equals("99999999999")) {
 
               return true;
          }
 
          return false;
     }
 
     private static String calcDigVerif(String num) {
          Integer primDig, segDig;
      int soma = 0, peso = 10;
      for (int i = 0; i < num.length(); i++)
           soma += Integer.parseInt(num.substring(i, i + 1)) * peso--;
 
      if (soma % 11 == 0 | soma % 11 == 1)
           primDig = new Integer(0);
          else
               primDig = new Integer(11 - (soma % 11));
 
      soma = 0;
          peso = 11;
          for (int i = 0; i < num.length(); i++)
               soma += Integer.parseInt(num.substring(i, i + 1)) * peso--;
 
          soma += primDig.intValue() * 2;
          if (soma % 11 == 0 | soma % 11 == 1)
               segDig = new Integer(0);
          else
               segDig = new Integer(11 - (soma % 11));
 
          return primDig.toString() + segDig.toString();
     }
     
     
     
     
 
     public static boolean isCNPJ(String CNPJ) {
    	 
    	// considera-se erro CNPJ's formados por uma sequencia de numeros iguais
	    if (CNPJ.equals("00000000000000") || CNPJ.equals("11111111111111") ||
	        CNPJ.equals("22222222222222") || CNPJ.equals("33333333333333") ||
	        CNPJ.equals("44444444444444") || CNPJ.equals("55555555555555") ||
	        CNPJ.equals("66666666666666") || CNPJ.equals("77777777777777") ||
	        CNPJ.equals("88888888888888") || CNPJ.equals("99999999999999") ||
	       (CNPJ.length() != 14)){
	       return(false);
	    }
	    
	    char dig13, dig14;
	    int sm, i, r, num, peso;
    	 
    	// "try" - protege o código para eventuais erros de conversao de tipo (int)
    	try{
    		// Calculo do 1o. Digito Verificador
	      sm = 0;
	      peso = 2;
	      for (i=11; i>=0; i--) {
	    	// converte o i-ésimo caractere do CNPJ em um número:
	    	// por exemplo, transforma o caractere '0' no inteiro 0
	    	// (48 eh a posição de '0' na tabela ASCII)
	        num = (int)(CNPJ.charAt(i) - 48);
	        sm = sm + (num * peso);
	        peso = peso + 1;
	        if (peso == 10)
	           peso = 2;
	      }
    	 
	      r = sm % 11;
	      if ((r == 0) || (r == 1)){
	         dig13 = '0';
	      }else{
	    	  dig13 = (char)((11-r) + 48);
	      }
    	 
	      // Calculo do 2o. Digito Verificador
	      sm = 0;
	      peso = 2;
	      for (i=12; i>=0; i--) {
	        num = (int)(CNPJ.charAt(i)- 48);
	        sm = sm + (num * peso);
	        peso = peso + 1;
	        if (peso == 10)
	           peso = 2;
	      }
    	 
	      r = sm % 11;
	      if ((r == 0) || (r == 1)){
	         dig14 = '0';
	      }else {
	    	  dig14 = (char)((11-r) + 48);
	      }
    	 
	      // Verifica se os dígitos calculados conferem com os dígitos informados.
    	  if ((dig13 == CNPJ.charAt(12)) && (dig14 == CNPJ.charAt(13))){
    	         return(true);
    	  }else{
    		  return(false);
    	  }
    	}catch (InputMismatchException erro) {
    		return(false);
    	}
     }
    	
}
